<?php

namespace App\Models\Account;

use App\Models\Common\DataScope;
use App\Models\Common\OperationLog;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Laravel\Passport\HasApiTokens;
use App\Helpers\Code;
use Carbon\Carbon;
use Illuminate\Support\Facades\Hash;
use App\Models\Common\Department;
use Illuminate\Support\Facades\Auth;
use App\Models\Notice\NoticeRecord;
use App\Models\Notice\SmsRecord;
use App\Models\Common\MenuAction;

class User extends Authenticatable
{

    use HasApiTokens,
        Notifiable,
        SoftDeletes;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'username', 'email', 'password', 'department_id', 'nickname', 'phone', 'job', 'gender', 'scope_id', 'data_scope',
        'parent_id', 'identity_card', 'telphone', 'province', 'city', 'area', 'address', 'region', 'region_province'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = ['password', 'remember_token'];
    public $params = ['username', 'department_id', 'phone', 'is_blocked'];
    public $sorters = ['username', 'nickname', 'phone', 'department_id', 'lastvisited_at'];

    /**
     *
     * @var type
     */
    protected $casts = ['session' => 'array'];

    public function usergroups()
    {
        return $this->belongsToMany('App\Models\Account\UserGroup', 'user_group_map_user', 'user_id', 'group_id')->withTimestamps();
    }

    public function department()
    {
        return $this->belongsTo('App\Models\Common\Department');
    }

    public function logs()
    {
        return $this->hasMany('App\Models\Common\OperationLog', 'user_id');
    }

    public function settings()
    {
        return $this->hasMany('App\Models\Account\UserSetting', 'user_id');
    }

    public function tokens()
    {
        return $this->hasMany('\App\Models\Account\OauthAccessToken', 'user_id');
    }

    public function findForPassport($username)
    {
        return $this->where('phone', $username)->first();
    }

    public function scope()
    {
        return $this->belongsTo('App\Models\Common\DataScope', 'scope_id');
    }

    /**
     * 添加用户
     * @param $data
     * @return int
     */
    public function addUser($data, $groups)
    {
        //数据域是否存在
        $scope = DataScope::where('id', $data['scope_id'])->first(['data_scope']);
        if (!$scope) {
            return Code::INSIDE_ERROR_1;
        }

        //部门是否存在
        $department = Department::find($data['department_id']);

        if (!$department) {
            return Code::INSIDE_EXIST_DEPENDENCE;
        }

        //直属上级是否存在
        if (isset($data['parent_id'])) {
            $parent = $this->find($data['parent_id'], ['id']);

            if (!$parent) {
                return Code::INSIDE_ERROR;
            }
        }

        //获取数据域下最后一位用户数据域
        $dataScope = $this->withTrashed()->where('scope_id', $data['scope_id'])->orderBy('data_scope', 'desc')->limit(1)->first(['data_scope']);

        //拼接用户数据域
        if (!$dataScope) {
            $data['data_scope'] = $scope->data_scope . '0001';
        } else {
            $data['data_scope'] = $this->_incDataOrg($dataScope->data_scope);
        }
        DB::beginTransaction();
        $model = $this->create($data);

        if ($model) {
            //添加用户组
            if (count($groups) > 0) {
                $groupNum = UserGroup::whereIn('id', $groups)->count();
                if ($groupNum != count($groups)) {
                    return Code::INSIDE_ERROR_2;
                }
                $model->usergroups()->sync($groups);
            }
            DB::commit();
            return $model;
        } else {
            DB::rollBack();
            return Code::INSIDE_FALSE;
        }
    }

    public function deleteUserSoft($id)
    {
        $model = $this->find($id);

        if (!$model) {
            return null;
        }
        try {
            //编辑删除电话
            $delPhone = '%' . $model->phone . '#del%';
            $phone = $this->onlyTrashed()->where('phone', 'like', $delPhone)->orderBy('deleted_at', 'desc')->limit(1)->first(['phone']);
            //重组电话
            if ($phone) {
                $model->phone = substr_replace($phone->phone, intval(substr($phone->phone, -1)) + 1, -1);
            } else {
                $model->phone = $model->phone . '#del_1';
            }

            //编辑删除邮箱
            $delEmail = '%' . $model->email . '#del%';
            $email = $this->onlyTrashed()->where('email', 'like', $delEmail)->orderBy('deleted_at', 'desc')->limit(1)->first(['email']);
            //重组邮箱
            if ($email) {
                $model->email = substr_replace($email->email, intval(substr($email->email, -1)) + 1, -1);
            } else {
                $model->email = $model->email . '#del_1';
            }

            DB::beginTransaction();
            $model->save();

            //删除用户菜单及其功能、数据域缓存
            UserCache::where('user_id', $id)->delete();

            //删除用户token
            $model->tokens()->delete();

            //删除用户
            $model->delete();

            DB::commit();
            return Code::INSIDE_TRUE;
        } catch (\Exception $e) {
            DB::rollBack();
            Log::channel('errordaily')->error($e->getFile() . ' 第' . $e->getLine() . '行，错误信息：' . $e->getMessage());
            return Code::INSIDE_DATABASE_ERROR;
        }
    }

    public function editUser($id, $data)
    {
        try {
            $model = $this->find($id);

            if (!$model) {
                return null;
            }

            //部门是否存在
            if (isset($data['department_id'])) {
                if (intval($data['department_id']) !== $model->department_id) {

                    $department = Department::find($data['department_id']);
                    if (!$department) {
                        return Code::INSIDE_EXIST_DEPENDENCE;
                    }
                }
            }

            //直属上级是否存在
            if (isset($data['parent_id'])) {
                if (intval($data['parent_id']) !== $model->parent_id) {
                    $parent = $this->where('id', '!=', $id)->find($data['parent_id'], ['id']);

                    if (!$parent) {
                        return Code::INSIDE_ERROR;
                    }
                }
            }

            //数据域是否存在
            if (isset($data['scope_id'])) {
                if (intval($data['scope_id']) !== $model->scope_id) {
                    $scope = DataScope::where('id', $data['scope_id'])->first(['data_scope']);
                    if (!$scope) {
                        return Code::INSIDE_ERROR_1;
                    }

                    //获取数据域下最后一位用户数据域
                    $dataScope = $this->withTrashed()->where('scope_id', $data['scope_id'])->orderBy('data_scope', 'desc')->limit(1)->first(['data_scope']);

                    //拼接用户数据域
                    if (!$dataScope) {
                        $data['data_scope'] = $scope->data_scope . '0001';
                    } else {
                        $data['data_scope'] = $this->_incDataOrg($dataScope->data_scope);
                    }
                }
            }
            DB::beginTransaction();

            //用户组是否存在
            if (isset($data['usergroups'])) {
                $groups = UserGroup::whereIn('id', $data['usergroups'])->count();
                if (count($data['usergroups']) !== $groups) {
                    return Code::INSIDE_ERROR_2;
                }

                $model->usergroups()->sync($data['usergroups']);
            }

            $res = $model->updateOrCreate(['id' => $id], $data);

            DB::commit();
            return $res;
        } catch (\Exception $e) {
            DB::rollBack();
            Log::channel('errordaily')->error($e->getFile() . ' 第' . $e->getLine() . '行，错误信息：' . $e->getMessage());
            return Code::INSIDE_DATABASE_ERROR;
        }
    }

    public function getUserList($limit, $sorter, $search)
    {
        $perPage = $limit > 0 ? $limit : $this->limit;
        $model = $this->with(['scope:id,full_title', 'department:id,title'])->orderBy($sorter[0], $sorter[1]);
        $model->select(['id', 'username', 'phone', 'nickname', 'is_blocked', 'lastvisited_at', 'department_id', 'scope_id', 'data_scope']);

        foreach ($search as $key => $value) {
            switch ($key) {
                case 'username':
                case 'phone':
                    $model->where($key, 'like', '%' . $value . '%');
                    break;
                case 'department_id':
                    $model->where($key, (int) $value);
                    break;
                case 'is_blocked':
                    $is_blocked = explode(',', $value);
                    if (count($is_blocked) > 0) {
                        $model->whereIn($key, $is_blocked);
                    }
                    break;
            }
        }

        return $model->paginate($perPage)->toArray();
    }

    public function getUserListAll()
    {
        return $this->where('id', '!=', Code::SUPER_ADMIN_USER_ID)->where('is_blocked', 0)->get(['id', 'username'])->toArray();
    }

    public function getEditUser($id)
    {
        $model = $this->with(['usergroups:user_groups.id,title'])
                ->find($id, ['id', 'parent_id', 'username', 'phone', 'job', 'email', 'nickname', 'gender', 'department_id', 'scope_id', 'identity_card', 'telphone', 'province', 'city', 'area', 'address', 'region', 'region_province']);

        if (!$model) {
            return null;
        }

        $data = $model->toArray();

        $userGroupTitle = [];
        $userGroupIds = [];
        if (isset($data['usergroups']) && count($data['usergroups']) > 0) {

            foreach ($data['usergroups'] as $v) {
                array_push($userGroupTitle, $v['title']);
                array_push($userGroupIds, $v['id']);
            }
        }
        $data['usergroup_title'] = $userGroupTitle;
        $data['usergroups'] = $userGroupIds;

        return $data;
    }

    public function getUser($id)
    {
        $model = $this->with(['scope:id,full_title', 'department:id,title', 'usergroups:user_groups.id,title'])
                ->find($id, ['id', 'parent_id', 'username', 'phone', 'job', 'email', 'nickname', 'gender', 'is_blocked', 'department_id', 'scope_id', 'created_at', 'activated_at', 'lastvisited_at', 'updated_at', 'data_scope', 'identity_card', 'telphone', 'province', 'city', 'area', 'address', 'avatar', 'region', 'region_province']);

        if (!$model) {
            return null;
        }

        $data = $model->toArray();

        $userGroupTitle = [];
        if (isset($data['usergroups']) && count($data['usergroups']) > 0) {
            $userGroupTitle = array_reduce($data['usergroups'], function ($res, $v) {
                $res[] = $v['title'];
                return $res;
            });
        }

        $data['usergroup_title'] = $userGroupTitle;
        unset($data['usergroups']);

        if ($data['parent_id']) {
            $data['parent_name'] = $this->find($data['parent_id'], ['username'])->username;
        } else {
            $data['parent_name'] = null;
        }

        if ($data['avatar']) {
            $data['avatar'] = asset('avatars/' . $data['avatar']);
        }

        return $data;
    }

    public function getCurrentUser($id)
    {
        $model = $this->select(['id', 'username', 'avatar'])->find($id);

        if (!$model) {
            return null;
        }

        $data = $model->toArray();

        if ($data['avatar']) {
            $data['avatar'] = asset('avatars/' . $data['avatar']);
        }

        $userId = Auth::id();

        $noticeCount = NoticeRecord::where('user_id', $userId)->where('is_readed', 0)->get(['id'])->count();
        $smsCount = SmsRecord::where('user_id', $userId)->where('is_readed', 0)->get(['id'])->count();

        $data['notifyCount'] = $noticeCount + $smsCount;

        return $data;
    }

    public function blockUser($id)
    {
        $model = $this->find($id);

        if (!$model) {
            return null;
        }

        if ($model->is_blocked === 1) {
            return Code::INSIDE_ERROR;
        }

        $model->is_blocked = 1;
        UserCache::where('user_id', $id)->delete();

        $model->tokens()->delete();

        return $model->save();
    }

    public function unblockUser($id)
    {
        $model = $this->find($id);

        if (!$model) {
            return null;
        }

        if ($model->is_blocked === 0) {
            return Code::INSIDE_ERROR;
        }

        $model->is_blocked = 0;

        return $model->save();
    }

    public function editPassword($id, $password)
    {
        $model = $this->find($id);

        if (!$model) {
            return null;
        }

        $model->password = $password;

        return $model->save();
    }

    public function isExist($id)
    {
        $model = $this->find($id);

        if (!$model) {
            return false;
        }

        return $model;
    }

    public function uploadAvatar($id, $filename)
    {
        $model = $this->find($id);

        $model->avatar = $filename;

        return $model->save();
    }

    public function deleteAvatar($id)
    {
        $model = $this->find($id);

        if (!$model) {
            return null;
        }

        $model->avatar = '';

        return $model->save();
    }

    public function deleteToken($id)
    {
        $model = $this->find($id);

        if (!$model) {
            return null;
        }

        return $model->tokens()->where('revoked', 1)->delete();
    }

    public function setSession($user)
    {
        /**
          $usergroup = new UserGroup();
          $permissions = $usergroup->getUsergroupPermissionAll($user->group_id);

          $data = [
          'permission' => ['expire' => now()->addMinutes(config('system.user_session_lefttime')), 'permissions' => array_flatten($permissions)],
          ];

          $session = $user->session ? $user->session : [];

          $user->session = merge($session, $data);
         * 
         */
        $user->lastvisited_at = new Carbon();

        $user->save();
    }

    /**
     * 获取指定用户信息
     * @param $id 用户id
     * @return array|null
     */
    public function getCurrentUserInfo($id)
    {
        $model = $this->with(['department:id,title'])
                ->select(['username', 'nickname', 'job', 'email', 'gender', 'phone', 'avatar', 'activated_at', 'lastvisited_at', 'department_id'])
                ->find($id);

        if (!$model) {
            return null;
        }

        $data = $model->toArray();

        if ($data['avatar']) {
            $data['avatar'] = asset('avatars/' . $data['avatar']);
        }

        return $data;
    }

    /**
     * 修改用户信息
     * @param $id
     * @param $data
     * @return null
     */
    public function editCurrentUserInfo($id, $data)
    {
        $model = $this->find($id);

        if (!$model) {
            return null;
        }

        return $model->updateOrCreate(['id' => $id], $data);
    }

    /**
     * 判断密码是否和原密码相同
     * @param $id
     * @param $data
     * @return null
     */
    public function checkPassword($id, $data)
    {
        $model = $this->find($id);

        if (!Hash::check($data['old_password'], $model->password)) {
            return false;
        }

        return true;
    }

    public function getUserMenuList($id)
    {
        $user = User::with('usergroups:user_groups.id')->find($id, ['id']);

        if (!$user) {
            return [];
        }

        $cache = UserCache::where('user_id', $id)->where('type', Code::CACHE_USER_MENU)->first(['cache', 'expired_at']);

        if ($cache) {
            $cacheArr = $cache->toArray();

            if (now() < $cacheArr['expired_at']) {
                return json_decode($cacheArr['cache']);
            }
        }

        $userArr = $user->toArray();

        $groupIds = array_column($userArr['usergroups'], 'id');

        $data = [];

        $menus = UserGroup::with(['menus', 'actions:user_group_menu_actions.menu_id,action_id,code'])->whereIn('id', $groupIds)->get(['id'])->toArray();

        $levelOne = [];
        $levelTwo = [];
        $levelThree = [];

        foreach ($menus as $item) {
            $actions = [];
            foreach ($item['actions'] as $action) {
                if (isset($actions[$action['menu_id']])) {
                    array_push($actions[$action['menu_id']], $action['code']);
                } else {
                    $actions[$action['menu_id']][] = $action['code'];
                }
            }

            foreach ($item['menus'] as $menu) {
                switch ($menu['level']) {
                    case 1:
                        $levelOne['sort'][$menu['id']] = $menu['sort'];
                        $levelOne['menus'][$menu['id']] = $this->_handleMenu($levelOne, $menu, $actions);
                        break;
                    case 2:
                        $levelTwo['sort'][$menu['id']] = $menu['sort'];
                        $levelTwo['parent'][$menu['id']] = $menu['parent_id'];
                        $levelTwo['menus'][$menu['id']] = $this->_handleMenu($levelTwo, $menu, $actions);
                        break;
                    case 3:
                        $levelThree['sort'][$menu['id']] = $menu['sort'];
                        $levelThree['parent'][$menu['id']] = $menu['parent_id'];
                        $levelThree['menus'][$menu['id']] = $this->_handleMenu($levelThree, $menu, $actions);
                        break;
                }
            }
        }

        if ($levelThree) {
            asort($levelThree['sort']);

            foreach ($levelThree['sort'] as $id => $sort) {
                $parent_id = $levelThree['parent'][$id];
                if ($levelTwo && isset($levelTwo['menus'][$parent_id])) {
                    $levelThree['menus'][$id]['actions'] = array_values(array_unique(array_flatten($levelThree['menus'][$id]['actions'])));
                    $levelTwo['menus'][$parent_id]['children'][] = $levelThree['menus'][$id];
                }
            }
        }

        if ($levelTwo) {
            asort($levelTwo['sort']);

            foreach ($levelTwo['sort'] as $id => $sort) {
                $parent_id = $levelTwo['parent'][$id];
                if ($levelOne && isset($levelOne['menus'][$parent_id])) {
                    $levelTwo['menus'][$id]['actions'] = array_values(array_unique(array_flatten($levelTwo['menus'][$id]['actions'])));
                    $levelOne['menus'][$parent_id]['children'][] = $levelTwo['menus'][$id];
                }
            }
        }

        if ($levelOne) {
            asort($levelOne['sort']);
            foreach ($levelOne['sort'] as $id => $sort) {
                $levelOne['menus'][$id]['actions'] = array_values(array_unique(array_flatten($levelOne['menus'][$id]['actions'])));
                $data[] = $levelOne['menus'][$id];
            }
        }
        
        $this->_handleUserCache(Code::CACHE_USER_MENU, $data, ['userId' => $user->id]);
        $this->_handleUserCache(Code::CACHE_USER_PERMISSION, '', ['groupIds' => $groupIds, 'userId' => $user->id]);

        return $data;
    }

    protected function _handleMenu($payload, $menu, $actions)
    {
        if (isset($payload['menus'][$menu['id']])) {
            if (isset($actions[$menu['id']])) {
                array_push($payload['menus'][$menu['id']]['actions'], $actions[$menu['id']]);
            }
            return $payload['menus'][$menu['id']];
        }

        $item = [];

        $item['name'] = $menu['name'];
        $item['path'] = $menu['path'];

        if ($menu['icon']) {
            $item['icon'] = $menu['icon'];
        }

        if ($menu['target']) {
            $item['target'] = $menu['target'];
        }

        if ($menu['hide_menu']) {
            $item['hideInMenu'] = true;
        }

        if ($menu['hide_breadcrumb']) {
            $item['hideInBreadcrumb'] = true;
        }

        $item['identity'] = $menu['identity'];

        if (isset($actions[$menu['id']])) {
            $item['actions'] = $actions[$menu['id']];
        } else {
            $item['actions'] = [];
        }

        return $item;
    }

    protected function _handleUserCache($type, $payload, $extra = [])
    {
        $data = ['user_id' => $extra['userId'], 'type' => $type, 'expired_at' => now()->addMinutes(config('system.user_cache_lefttime'))];
        switch ($type) {
            case Code::CACHE_USER_MENU:
                $data['cache'] = json_encode($payload);
                break;
            case Code::CACHE_USER_PERMISSION:
                $cache = [];
                $apis = [];
                $scopes = [];
                $actionIds = [];

                //获取用户组功能下数据域
                $actionScopes = UserGroupMenuActionScope::whereIn('group_id', $extra['groupIds'])->get(['action_id', 'scope_id'])->toArray();

                //获取用户组功能
                $menuActions = UserGroupMenuAction::whereIn('group_id', $extra['groupIds'])->get(['action_id'])->toArray();

                //筛选功能id
                $actionScopeIds = array_column($actionScopes, 'action_id');
                $menuActionIds = array_column($menuActions, 'action_id');
                $diffActionIds = array_unique(array_diff($menuActionIds, $actionScopeIds));

                //功能未添加数据域是获取接口
                if (count($diffActionIds) > 0) {
                    $menuActionPermissions = MenuAction::with(['permissions:slug'])->whereIn('id', $diffActionIds)->get(['id'])->toArray();
                    $actionPermissionSlugs = array_column($menuActionPermissions, 'permissions');
                    $actionPermissions = [];
                    foreach ($actionPermissionSlugs as $permissionKey => $permissionValue) {
                        $actionPermissions = array_merge($actionPermissions, array_column($permissionValue, 'slug'));
                    }
                    $apis = array_unique($actionPermissions);
                }

                //功能添加数据域获取接口
                $actionScopesArr = [];
                $scopeIds = [];
                foreach ($actionScopes as $item) {
                    $scopeIds[] = $item['scope_id'];
                    if (isset($actionScopesArr[$item['action_id']])) {
                        array_push($actionScopesArr[$item['action_id']], $item['scope_id']);
                    } else {
                        $actionScopesArr[$item['action_id']][] = $item['scope_id'];
                    }
                }

                $dataScopes = DataScope::whereIn('id', array_unique($scopeIds))->pluck('data_scope', 'id')->toArray();

                foreach ($actionScopesArr as $actionId => $scopeIds) {
                    $slugs = [];
//                    if (array_has($actionIds, [$actionId])) {
//                        $slugs = $actionIds[$actionId];
//                    } else {
                    $permissions = MenuAction::with(['permissions:slug'])->where('id', $actionId)->get(['id'])->toArray();

                    if (isset($permissions[0]) && count($permissions[0])) {
                        $slugs = array_column($permissions[0]['permissions'], 'slug');
                        array_push($actionIds, [$actionId => $slugs]);
                    }
//                    }

                    $scopeIds = array_unique($scopeIds);

                    foreach ($slugs as $routerName) {
                        $apis[] = $routerName;

                        foreach ($scopeIds as $scopeId) {
                            if (isset($dataScopes[$scopeId])) {
                                $scopes[$routerName][0][] = $dataScopes[$scopeId];
                                $scopes[$routerName][1][] = strlen($dataScopes[$scopeId]);
                            }
                        }
                    }
                }

                $cache['apis'] = array_unique($apis);
                foreach ($scopes as $scopeKey => $scopeValue) {
                    if (count($scopeValue) > 0) {
                        $scopeUnique = array_keys(array_unique($scopeValue[0]));
                        $scopeKeys = array_keys($scopeValue[0]);
                        $delKey = array_diff($scopeKeys, $scopeUnique);
                        foreach ($delKey as $delKeyValue) {
                            unset($scopes[$scopeKey][0][$delKeyValue]);
                            unset($scopes[$scopeKey][1][$delKeyValue]);
                        }
                        $scopes[$scopeKey][0] = array_values($scopes[$scopeKey][0]);
                        $scopes[$scopeKey][1] = array_values($scopes[$scopeKey][1]);
                    }
                }

                $cache['scopes'] = $scopes;

                $data['cache'] = json_encode($cache);
                break;
        }
        $userCache = new UserCache();
        $userCache->where('user_id', $extra['userId'])->where('type', $type)->delete();
        $userCache->addCache($data);
    }

    /**
     * 编辑数据域
     * @param $dataOrg
     * @return string
     */
    private function _incDataOrg($dataOrg)
    {
        $pre = substr($dataOrg, 0, strlen($dataOrg) - 4);
        $seed = intval(substr($dataOrg, -4)) + 1;

        return $pre . str_pad($seed, 4, "0", STR_PAD_LEFT);
    }

    /**
     * 删除用户菜单cache
     * @param $id
     * @return null
     */
    public function clearUserCache($id)
    {
        $model = $this->find($id);

        if (!$model) {
            return null;
        }

        return UserCache::where('user_id', $id)->delete();
    }

    /**
     * 删除用户token
     * @param $id
     * @return null
     */
    public function clearUserToken($id)
    {
        $model = $this->find($id);

        if (!$model) {
            return null;
        }

        return $model->tokens()->delete();
    }

    /**
     * 初始化用户密码
     * @param $id
     * @return null
     */
    public function resetUserPassword($id)
    {
        $model = $this->find($id);

        if (!$model) {
            return null;
        }

        $model->password = Hash::make(config('system.user_default_password'));

        return $model->save();
    }

    /**
     * 获取用户登录信息列表
     * @param $limit
     * @param $sorter
     * @param $id
     * @return mixed
     */
    public function getUserLoginLogList($limit, $sorter, $id)
    {
        $model = $this->find($id);

        if (!$model) {
            return null;
        }

        $perPage = $limit > 0 ? $limit : $this->limit;
        $model = UserLog::with(['user:id,username'])->orderBy($sorter[0], $sorter[1]);
        $model->select(['id', 'user_id', 'type', 'ip', 'address', 'created_at']);

        return $model->where('user_id', $id)->paginate($perPage)->toArray();
    }

    /**
     * 获取用户操作日志列表
     * @param $limit
     * @param $sorter
     * @param $id
     * @return mixed
     */
    public function getUserOperationLogList($limit, $sorter, $search, $id)
    {
        $model = $this->find($id);

        if (!$model) {
            return null;
        }

        $perPage = $limit > 0 ? $limit : $this->limit;
        $model = OperationLog::with(['user:id,username'])->orderBy($sorter[0], $sorter[1]);
        $model->select(['id', 'user_id', 'method', 'path', 'ip', 'description', 'client', 'browser', 'created_at']);

        if (!empty($search['start_time'])) {
            $model->where('created_at', '>=', $search['start_time']);
        }

        if (!empty($search['end_time'])) {
            $model->where('created_at', '<=', $search['end_time']);
        }

        return $model->where('user_id', $id)->paginate($perPage)->toArray();
    }

    /**
     * 获取用户权限全部
     * @param $id
     * @return null
     * todo:需要后期完善
     */
    public function getUserPermission($id)
    {
        $model = $this->find($id, ['id', 'username']);

        if (!$model) {
            return null;
        }

        return $this->getUserMenuList($id);
    }

    public function resetUserCache()
    {
        try {
            DB::beginTransaction();
            DB::table('user_caches')->delete();
            $userIds = $this->all('id')->toArray();

            foreach ($userIds as $v) {
                $this->getUserMenuList($v['id']);
            }

            DB::commit();
            return Code::INSIDE_TRUE;
        } catch (\Exception $e) {
            DB::rollBack();
            return Code::INSIDE_DATABASE_ERROR;
        }
    }

    public function clearUserAvatar($id)
    {
        $model = $this->find($id);

        if (!$model) {
            return null;
        }

        $model->avatar = '';

        return $model->save();
    }

}
